using System;
using System.IO;

namespace Servlets.Api
{
	public class ResponseStream
	{
		private static readonly string EOL = "\r\n";
		private IResponse response;
		private MemoryStream buffer = new MemoryStream();
		private StreamWriter bufferWriter;
		private StreamWriter writer; 
		
		private BinaryWriter _binaryWriter;
		private BinaryWriter BinaryWriter {
			get {
				return _binaryWriter ?? (_binaryWriter = new BinaryWriter(buffer));
			}
		}
		
		public ResponseStream(Stream stream, IResponse response)
		{
			this.response = response;
			writer = new StreamWriter(stream);
			bufferWriter = new StreamWriter(buffer);
			
			buffer.Seek(0, SeekOrigin.Begin);
		}
		
		public void Clear() {
			buffer.Seek(0, SeekOrigin.Begin);
			buffer.SetLength(0L);
		}
		
		public void Write(string value) {
			bufferWriter.Write(value);
			bufferWriter.Flush();
		}
				
		public void WriteLine(string value) {
			this.Write(value + "\r\n");
		}
		
		public void Write(object value) {
			this.Write(value.ToString());
		}
				
		public void WriteLine(object value) {
			this.WriteLine(value.ToString());
		}
		
		public void Write(byte[] bytes) {
			BinaryWriter.Write(bytes);
			BinaryWriter.Flush();
		}
		
		public void Close () {
			bufferWriter.Flush();
			buffer.Flush();
			BinaryWriter.Flush();
			buffer.Seek(0, SeekOrigin.Begin);
			
			byte[] content = new byte[buffer.Length];
			buffer.Read(content, 0, content.Length);
			
			writer.Write("{0} {1}{2}", response.HttpVersion, response.HttpStatus, EOL);
			foreach(HttpProperty property in response.AllProperties) {
				writer.Write("{0}: {1}{2}", property, response.GetProperty(property), EOL);
			}
			foreach(Cookie cookie in response.Cookies) {
				string cookiestr = "Set-Cookie: " + cookie.ToString();
				writer.Write(cookiestr + EOL);
			}
			writer.Write("Content-Length: " + content.Length +EOL);
			writer.Write(EOL);
			writer.Flush();
			writer.BaseStream.Write(content, 0, content.Length);
			writer.BaseStream.Flush();
			writer.Close();
		}
		
	}
}

